//
//  ContentView.swift
//  CooImage
//
//  Created by jerry on 2025/8/16.
//

import SwiftUI

struct ContentView: View {
    @State private var currentScale: CGFloat = 1.0
    @State private var lastScale: CGFloat = 1.0
    @State private var currentOffset: CGSize = .zero
    @State private var lastOffset: CGSize = .zero
    @State private var image: NSImage? = nil
    @State private var showToolbar: Bool = true
    @State private var rotationAngle: Double = 0.0
    
    // 图片浏览相关状态
    @State private var currentImageURL: URL? = nil
    @State private var directoryImages: [URL] = []
    @State private var currentImageIndex: Int = 0
    
    // 目录访问相关
    @State private var currentDirectoryURL: URL? = nil
    @State private var directoryBookmark: Data? = nil
    
    // 视图状态
    @State private var showingImageGrid: Bool = false
    
    var body: some View {
        Group {
            if showingImageGrid {
                // 显示图片网格视图
                ImageGridView(
                    imageURLs: directoryImages,
                    onSelectImage: { url in
                        // 当用户选择一张图片时
                        if let image = NSImage(contentsOf: url) {
                            self.image = image
                            self.currentImageURL = url
                            
                            // 找到当前图片在数组中的索引
                            if let index = directoryImages.firstIndex(of: url) {
                                self.currentImageIndex = index
                            }
                            
                            // 重置视图并切换到图片查看模式
                            resetView()
                            withAnimation {
                                showingImageGrid = false
                            }
                        }
                    }
                )
                .toolbar {
                    ToolbarItem(placement: .navigation) {
                        Button("返回") {
                            withAnimation {
                                showingImageGrid = false
                            }
                        }
                    }
                }
            } else {
                // 显示单张图片查看视图
                VStack(spacing: 0) {
                    if showToolbar && image != nil {
                        ToolbarView(
                            zoomIn: {
                                withAnimation(.spring()) {
                                    currentScale *= 1.25
                                    lastScale = currentScale
                                }
                            },
                            zoomOut: {
                                withAnimation(.spring()) {
                                    currentScale *= 0.8
                                    lastScale = currentScale
                                }
                            },
                            resetView: {
                                resetView()
                            },
                            toggleToolbar: {
                                showToolbar.toggle()
                            },
                            rotateClockwise: {
                                withAnimation {
                                    rotationAngle += 90.0
                                    if rotationAngle >= 360.0 {
                                        rotationAngle -= 360.0
                                    }
                                }
                            },
                            rotateCounterClockwise: {
                                withAnimation {
                                    rotationAngle -= 90.0
                                    if rotationAngle < 0.0 {
                                        rotationAngle += 360.0
                                    }
                                }
                            },
                            previousImage: {
                                print("点击了上一张按钮")
                                loadPreviousImage()
                            },
                            nextImage: {
                                print("点击了下一张按钮")
                                loadNextImage()
                            },
                            hasPreviousImage: directoryImages.count > 1,
                            hasNextImage: directoryImages.count > 1,
                            requestDirectoryAccess: {
                                requestDirectoryAccessForCurrentImage()
                            },
                            showDirectoryAccessButton: directoryImages.count == 1 && currentImageURL != nil
                        )
                    }
                    
                    ZStack {
                        Color(.windowBackgroundColor).edgesIgnoringSafeArea(.all)
                        
                        if let image = image {
                            ScrollableImageView(
                                image: image,
                                currentScale: $currentScale,
                                lastScale: $lastScale,
                                rotationAngle: rotationAngle
                            )
                            
                            if !showToolbar {
                                VStack {
                                    Spacer()
                                    HStack {
                                        Spacer()
                                        Button(action: {
                                            withAnimation {
                                                showToolbar = true
                                            }
                                        }) {
                                            Image(systemName: "chevron.down")
                                                .padding(8)
                                                .background(Color(.controlBackgroundColor))
                                                .clipShape(Circle())
                                                .shadow(radius: 2)
                                        }
                                        .buttonStyle(.borderless)
                                        .padding()
                                        .help("显示工具栏")
                                    }
                                }
                            }
                            
                            // 添加浏览所有图片的按钮
                            VStack {
                                HStack {
                                    Spacer()
                                    Button(action: {
                                        withAnimation {
                                            showingImageGrid = true
                                        }
                                    }) {
                                        Image(systemName: "square.grid.2x2")
                                            .padding(8)
                                            .background(Color(.controlBackgroundColor))
                                            .clipShape(Circle())
                                            .shadow(radius: 2)
                                    }
                                    .buttonStyle(.borderless)
                                    .padding()
                                    .help("浏览所有图片")
                                }
                                Spacer()
                            }
                        } else {
                            VStack {
                                Image(systemName: "photo")
                                    .resizable()
                                    .aspectRatio(contentMode: .fit)
                                    .frame(width: 100, height: 100)
                                    .foregroundColor(.gray)
                                
                                Text("拖拽图片到此处或点击打开")
                                    .padding()
                                
                                VStack {
                                    Button("打开图片") {
                                        openImage()
                                    }
                                    .padding(.bottom, 8)
                                    
                                    Button("打开图片目录") {
                                        openDirectory()
                                    }
                                }
                                .padding()
                            }
                        }
                    }
                }
            }
        }
        .onAppear {
            setupNotificationObserver()
        }
        .onDisappear {
            removeNotificationObserver()
        }
        .frame(minWidth: 600, minHeight: 400)
        .onDrop(of: ["public.file-url"], isTargeted: nil) { providers in
            if let provider = providers.first {
                provider.loadDataRepresentation(forTypeIdentifier: "public.file-url") { data, error in
                    if let data = data, let path = NSString(data: data, encoding: 4), let url = URL(string: path as String) {
                        DispatchQueue.main.async {
                            self.loadImage(from: url)
                        }
                    }
                }
            }
            return true
        }
    }
    
    
    private func openImage() {
        let panel = NSOpenPanel()
        panel.message = "选择图片或目录"
        panel.prompt = "选择"
        panel.allowsMultipleSelection = true  // 允许选择多个文件
        panel.canChooseDirectories = true     // 允许选择目录
        panel.canChooseFiles = true
        // 不限制文件类型，以便能够选择目录
        // panel.allowedContentTypes = [.image]
        
        if panel.runModal() == .OK {
            let selectedURLs = panel.urls
            if selectedURLs.isEmpty { return }
            
            // 检查是否选择了目录
            if let directoryURL = selectedURLs.first, let values = try? directoryURL.resourceValues(forKeys: [.isDirectoryKey]), values.isDirectory == true {
                // 用户选择了目录，申请访问权限后加载目录中的所有图片
                requestDirectoryAccess(for: directoryURL) { granted in
                    DispatchQueue.main.async {
                        if granted {
                            self.loadImagesFromDirectory(directoryURL)
                        }
                    }
                }
            } else {
                // 用户选择了一个或多个图片文件，直接加载不申请目录权限
                self.directoryImages = selectedURLs.sorted { $0.lastPathComponent < $1.lastPathComponent }
                
                // 加载第一张图片
                if let firstURL = selectedURLs.first, let image = NSImage(contentsOf: firstURL) {
                    self.image = image
                    self.currentImageURL = firstURL
                    self.currentImageIndex = 0
                    self.resetView()
                    
                    print("已加载 \(selectedURLs.count) 张图片")
                    for (index, url) in selectedURLs.enumerated() {
                        print("[\(index)] \(url.lastPathComponent)")
                    }
                }
            }
        }
    }
    
    private func openDirectory() {
        let panel = NSOpenPanel()
        panel.message = "选择包含图片的目录"
        panel.prompt = "选择"
        panel.allowsMultipleSelection = false
        panel.canChooseDirectories = true
        panel.canChooseFiles = false
        
        if panel.runModal() == .OK, let directoryURL = panel.url {
            print("选择了目录: \(directoryURL.path)")
            // 申请目录访问权限
            requestDirectoryAccess(for: directoryURL) { granted in
                DispatchQueue.main.async {
                    if granted {
                        self.loadImagesFromDirectory(directoryURL)
                    }
                }
            }
        }
    }
    
    private func loadImagesFromDirectory(_ directoryURL: URL) {
        // 保存目录URL
        self.currentDirectoryURL = directoryURL
        
        // 创建安全书签以获取持续访问权限
        do {
            let bookmarkData = try directoryURL.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
            self.directoryBookmark = bookmarkData
            
            // 立即使用书签访问目录
            var isStale = false
            if let url = try? URL(resolvingBookmarkData: bookmarkData, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale) {
                if url.startAccessingSecurityScopedResource() {
                    defer {
                        url.stopAccessingSecurityScopedResource()
                    }
                    
                    // 加载目录中的所有图片
                    loadAllImagesInDirectory(url, showGridView: true)
                } else {
                    print("无法访问目录")
                }
            }
        } catch {
            print("创建书签失败: \(error)")
            // 尝试直接加载目录内容
            loadAllImagesInDirectory(directoryURL, showGridView: true)
        }
    }
    
    private func requestDirectoryAccessForCurrentImage() {
        guard let currentURL = currentImageURL else { return }
        let directoryURL = currentURL.deletingLastPathComponent()
        
        requestDirectoryAccess(for: directoryURL) { granted in
            DispatchQueue.main.async {
                if granted {
                    // 权限获得后，加载目录中的所有图片
                    self.loadAllImagesInDirectory(directoryURL, showGridView: false)
                    
                    // 找到当前图片在目录中的索引
                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                        if let index = self.directoryImages.firstIndex(of: currentURL) {
                            self.currentImageIndex = index
                        }
                    }
                }
            }
        }
    }
    
    private func requestDirectoryAccess(for directoryURL: URL, completion: @escaping (Bool) -> Void) {
        // 显示权限申请对话框
        let alert = NSAlert()
        alert.messageText = "访问目录权限"
        alert.informativeText = "CooImage 需要访问图片所在目录以便浏览同目录下的其他图片。是否允许访问目录：\n\(directoryURL.path)"
        alert.addButton(withTitle: "允许")
        alert.addButton(withTitle: "拒绝")
        alert.alertStyle = .informational
        
        let response = alert.runModal()
        
        if response == .alertFirstButtonReturn {
            // 用户同意，创建安全书签
            do {
                let bookmarkData = try directoryURL.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
                self.directoryBookmark = bookmarkData
                self.currentDirectoryURL = directoryURL
                
                print("已获得目录访问权限: \(directoryURL.path)")
                completion(true)
            } catch {
                print("创建安全书签失败: \(error)")
                completion(false)
            }
        } else {
            print("用户拒绝了目录访问权限")
            completion(false)
        }
    }
    
    private func loadAllImagesInDirectory(_ directoryURL: URL, showGridView: Bool = false) {
        // 在后台线程加载图片列表
        DispatchQueue.global(qos: .userInitiated).async {
            let fileManager = FileManager.default
            do {
                // 获取目录内容
                let fileURLs = try fileManager.contentsOfDirectory(at: directoryURL, includingPropertiesForKeys: nil)
                
                // 过滤出所有图片文件
                let imageExtensions = ["jpg", "jpeg", "png", "gif", "bmp", "tiff", "heic"]
                let imageURLs = fileURLs.filter { url in
                    let fileExtension = url.pathExtension.lowercased()
                    return imageExtensions.contains(fileExtension)
                }.sorted { $0.lastPathComponent < $1.lastPathComponent }
                
                // 在主线程更新UI
                DispatchQueue.main.async {
                    if imageURLs.isEmpty {
                        print("目录中没有找到图片")
                        return
                    }
                    
                    self.directoryImages = imageURLs
                    
                    // 找到当前图片在列表中的索引
                    if let currentURL = self.currentImageURL,
                       let index = imageURLs.firstIndex(of: currentURL) {
                        self.currentImageIndex = index
                    } else if !imageURLs.isEmpty && showGridView {
                        // 只有在显示网格视图时才自动设置第一张为当前图片
                        self.currentImageIndex = 0
                        if let firstImage = NSImage(contentsOf: imageURLs[0]) {
                            self.image = firstImage
                            self.currentImageURL = imageURLs[0]
                            self.resetView()
                        }
                    }
                    
                    print("从目录加载了 \(imageURLs.count) 张图片")
                    
                    // 如果需要显示网格视图
                    if showGridView {
                        self.showingImageGrid = true
                    }
                }
            } catch {
                DispatchQueue.main.async {
                    print("读取目录内容失败: \(error)")
                }
            }
        }
    }
    
    private func loadImage(from url: URL) {
        // 直接加载单张图片，不申请目录权限
        if let image = NSImage(contentsOf: url) {
            self.image = image
            self.currentImageURL = url
            self.resetView()
            
            // 只将这一张图片添加到图片列表中
            self.directoryImages = [url]
            self.currentImageIndex = 0
        }
    }
    
    private func loadPreviousImage() {
        guard !directoryImages.isEmpty else {
            print("图片列表为空，无法加载上一张")
            return
        }
        
        print("当前索引: \(currentImageIndex), 图片总数: \(directoryImages.count)")
        let newIndex = (currentImageIndex - 1 + directoryImages.count) % directoryImages.count
        currentImageIndex = newIndex
        print("切换到上一张图片，新索引: \(newIndex)")
        
        let imageURL = directoryImages[newIndex]
        print("尝试加载图片: \(imageURL.path)")
        
        if let image = NSImage(contentsOf: imageURL) {
            print("成功加载图片")
            self.image = image
            self.currentImageURL = imageURL
            resetView()
        } else {
            print("加载图片失败")
        }
    }
    
    private func loadNextImage() {
        guard !directoryImages.isEmpty else {
            print("图片列表为空，无法加载下一张")
            return
        }
        
        print("当前索引: \(currentImageIndex), 图片总数: \(directoryImages.count)")
        let newIndex = (currentImageIndex + 1) % directoryImages.count
        currentImageIndex = newIndex
        print("切换到下一张图片，新索引: \(newIndex)")
        
        let imageURL = directoryImages[newIndex]
        print("尝试加载图片: \(imageURL.path)")
        
        if let image = NSImage(contentsOf: imageURL) {
            print("成功加载图片")
            self.image = image
            self.currentImageURL = imageURL
            resetView()
        } else {
            print("加载图片失败")
        }
    }
    
    private func resetView() {
        withAnimation(.spring()) {
            currentScale = 1.0
            lastScale = 1.0
            currentOffset = .zero
            lastOffset = .zero
        }
    }
    
    private func moveImage(dx: CGFloat, dy: CGFloat) {
        currentOffset = CGSize(
            width: currentOffset.width + dx,
            height: currentOffset.height + dy
        )
        lastOffset = currentOffset
    }
    
    private func setupNotificationObserver() {
        // 打开图片
        NotificationCenter.default.addObserver(
            forName: NSNotification.Name("OpenImage"),
            object: nil,
            queue: .main
        ) { _ in
            openImage()
        }
        
        // 添加键盘事件监听
        NSEvent.addLocalMonitorForEvents(matching: .keyDown) { event in
            if self.image != nil {
                if event.keyCode == 123 { // 左箭头键
                    self.loadPreviousImage()
                    return nil
                } else if event.keyCode == 124 { // 右箭头键
                    self.loadNextImage()
                    return nil
                }
            }
            return event
        }
        
        // 放大
        NotificationCenter.default.addObserver(
            forName: NSNotification.Name("ZoomIn"),
            object: nil,
            queue: .main
        ) { _ in
            withAnimation(.spring()) {
                currentScale *= 1.25
                lastScale = currentScale
            }
        }
        
        // 缩小
        NotificationCenter.default.addObserver(
            forName: NSNotification.Name("ZoomOut"),
            object: nil,
            queue: .main
        ) { _ in
            withAnimation(.spring()) {
                currentScale *= 0.8
                lastScale = currentScale
            }
        }
        
        // 重置大小
        NotificationCenter.default.addObserver(
            forName: NSNotification.Name("ResetZoom"),
            object: nil,
            queue: .main
        ) { _ in
            resetView()
        }
        
        // 顺时针旋转
        NotificationCenter.default.addObserver(
            forName: NSNotification.Name("RotateClockwise"),
            object: nil,
            queue: .main
        ) { _ in
            withAnimation {
                rotationAngle += 90.0
                if rotationAngle >= 360.0 {
                    rotationAngle -= 360.0
                }
            }
        }
        
        // 逆时针旋转
        NotificationCenter.default.addObserver(
            forName: NSNotification.Name("RotateCounterClockwise"),
            object: nil,
            queue: .main
        ) { _ in
            withAnimation {
                rotationAngle -= 90.0
                if rotationAngle < 0.0 {
                    rotationAngle += 360.0
                }
            }
        }
        
        // 切换工具栏
        NotificationCenter.default.addObserver(
            forName: NSNotification.Name("ToggleToolbar"),
            object: nil,
            queue: .main
        ) { _ in
            withAnimation {
                showToolbar.toggle()
            }
        }
        
        // 上一张图片
        NotificationCenter.default.addObserver(
            forName: NSNotification.Name("PreviousImage"),
            object: nil,
            queue: .main
        ) { _ in
            print("收到上一张图片通知")
            loadPreviousImage()
        }
        
        // 下一张图片
        NotificationCenter.default.addObserver(
            forName: NSNotification.Name("NextImage"),
            object: nil,
            queue: .main
        ) { _ in
            print("收到下一张图片通知")
            loadNextImage()
        }
    }
    
    private func removeNotificationObserver() {
        let notificationNames = [
            "OpenImage",
            "ZoomIn",
            "ZoomOut",
            "ResetZoom",
            "RotateClockwise",
            "RotateCounterClockwise",
            "ToggleToolbar",
            "PreviousImage",
            "NextImage"
        ]
        
        for name in notificationNames {
            NotificationCenter.default.removeObserver(
                self,
                name: NSNotification.Name(name),
                object: nil
            )
        }
    }
}

#Preview {
    ContentView()
}